package com.sisyphus.tron.transaction;

import com.google.protobuf.ByteString;
import com.sisyphus.tron.TronAndroid;

import org.spongycastle.util.encoders.Hex;
import org.tron.common.crypto.ECKey;
import org.tron.common.utils.TransactionUtils;
import org.tron.protos.Contract;
import org.tron.walletserver.GrpcClient;

import org.tron.protos.Protocol;

import java.math.BigInteger;

public class TRXTransactionBuilder implements TransactionBuilder {

    private String to;

    private String from;

    private Long amount;

    private GrpcClient grpcClient;


    /**
     * 创建一个未签名的TRX转账交易
     *
     * @param hexTo   转入TRX 的地址
     * @param hexFrom 转出trx的可选地址
     * @param amount  要发送的TRX 数量
     */
    public TRXTransactionBuilder(String hexTo, String hexFrom, Long amount, String fullNode, String solidityNode) {
        this.to = hexTo;
        this.from = hexFrom;
        this.amount = amount;
        this.grpcClient = new GrpcClient(fullNode, solidityNode); // TODO: 未完成
    }


    @Override
    public String sign(String privateKey) {
        Contract.TransferContract contract = createTransferContract(TronAndroid.decode58Check(to), TronAndroid.decode58Check(from), amount);
        Protocol.Transaction transaction = grpcClient.createTransaction(contract).getTransaction();
        Protocol.Transaction transactionSigned = TransactionUtils.setTimestamp(transaction);

        // 返回交易签名
        return Hex.toHexString(
                TransactionUtils.sign(
                        transactionSigned,
                        ECKey.fromPrivate(new BigInteger(privateKey, 16))
                ).toByteArray()
        );
    }


    @Override
    public void broadcast(String privateKey) {
        Contract.TransferContract contract = createTransferContract(TronAndroid.decode58Check(to), TronAndroid.decode58Check(from), amount);
        Protocol.Transaction transaction = grpcClient.createTransaction(contract).getTransaction();
        Protocol.Transaction transactionSigned = TransactionUtils.setTimestamp(transaction);

        // 广播交易
        grpcClient.broadcastTransaction(
                TransactionUtils.sign(
                        transactionSigned,
                        ECKey.fromPrivate(new BigInteger(privateKey, 16))
                )
        );
    }


    private Contract.TransferContract createTransferContract(byte[] to, byte[] from, long amount) {
        Contract.TransferContract.Builder builder = Contract.TransferContract.newBuilder();
        ByteString bsTo = ByteString.copyFrom(to);
        ByteString bsOwner = ByteString.copyFrom(from);
        builder.setToAddress(bsTo);
        builder.setOwnerAddress(bsOwner);
        builder.setAmount(amount);
        return builder.build();
    }




}
